import { defineStore } from 'pinia'
import { ref, computed } from 'vue'

export interface Notification {
  id: string
  type: 'success' | 'error' | 'warning' | 'info'
  title: string
  message?: string
  duration?: number
  persistent?: boolean
  actions?: NotificationAction[]
  timestamp: Date
}

export interface NotificationAction {
  label: string
  action: () => void
  type?: 'primary' | 'secondary'
}

export interface LoadingState {
  id: string
  message: string
  progress?: number
  cancellable?: boolean
  onCancel?: () => void
}

export interface DialogState {
  id: string
  type: 'confirm' | 'prompt' | 'custom'
  title: string
  message?: string
  confirmText?: string
  cancelText?: string
  onConfirm?: (value?: any) => void
  onCancel?: () => void
  component?: any
  props?: Record<string, any>
}

export const useUIStore = defineStore('ui', () => {
  // State
  const notifications = ref<Notification[]>([])
  const loadingStates = ref<LoadingState[]>([])
  const dialogs = ref<DialogState[]>([])
  const sidebarCollapsed = ref(false)
  const theme = ref<'light' | 'dark'>('light')
  const currentView = ref<'history' | 'search' | 'recovery' | 'diff'>('history')
  const keyboardShortcutsEnabled = ref(true)
  const autoSave = ref(true)
  const language = ref<'zh' | 'en'>('zh')
  
  // Layout state
  const windowSize = ref({ width: 1200, height: 800 })
  const panelSizes = ref({
    sidebar: 300,
    main: 600,
    details: 300
  })

  // Getters
  const hasNotifications = computed(() => notifications.value.length > 0)
  
  const hasLoadingStates = computed(() => loadingStates.value.length > 0)
  
  const hasDialogs = computed(() => dialogs.value.length > 0)
  
  const isLoading = computed(() => loadingStates.value.length > 0)
  
  const currentDialog = computed(() => 
    dialogs.value.length > 0 ? dialogs.value[dialogs.value.length - 1] : null
  )
  
  const unreadNotifications = computed(() => 
    notifications.value.filter(n => !n.persistent)
  )

  const persistentNotifications = computed(() => 
    notifications.value.filter(n => n.persistent)
  )

  // Actions - Notifications
  function showNotification(
    type: Notification['type'],
    title: string,
    message?: string,
    options?: Partial<Omit<Notification, 'id' | 'type' | 'title' | 'timestamp'>>
  ) {
    const notification: Notification = {
      id: generateId(),
      type,
      title,
      message,
      duration: options?.duration ?? (type === 'error' ? 0 : 5000),
      persistent: options?.persistent ?? false,
      actions: options?.actions,
      timestamp: new Date()
    }
    
    notifications.value.push(notification)
    
    // Auto remove non-persistent notifications
    if (notification.duration && notification.duration > 0 && !notification.persistent) {
      setTimeout(() => {
        removeNotification(notification.id)
      }, notification.duration)
    }
    
    return notification.id
  }

  function showSuccess(title: string, message?: string, options?: Partial<Notification>) {
    return showNotification('success', title, message, options)
  }

  function showError(title: string, message?: string, options?: Partial<Notification>) {
    return showNotification('error', title, message, { ...options, duration: 0 })
  }

  function showWarning(title: string, message?: string, options?: Partial<Notification>) {
    return showNotification('warning', title, message, options)
  }

  function showInfo(title: string, message?: string, options?: Partial<Notification>) {
    return showNotification('info', title, message, options)
  }

  function removeNotification(id: string) {
    const index = notifications.value.findIndex(n => n.id === id)
    if (index > -1) {
      notifications.value.splice(index, 1)
    }
  }

  function clearNotifications() {
    notifications.value = []
  }

  function clearNotificationsByType(type: Notification['type']) {
    notifications.value = notifications.value.filter(n => n.type !== type)
  }

  // Actions - Loading States
  function startLoading(
    message: string,
    options?: Partial<Omit<LoadingState, 'id' | 'message'>>
  ): string {
    const loadingState: LoadingState = {
      id: generateId(),
      message,
      progress: options?.progress,
      cancellable: options?.cancellable ?? false,
      onCancel: options?.onCancel
    }
    
    loadingStates.value.push(loadingState)
    return loadingState.id
  }

  function updateLoading(id: string, updates: Partial<Omit<LoadingState, 'id'>>) {
    const index = loadingStates.value.findIndex(l => l.id === id)
    if (index > -1) {
      loadingStates.value[index] = { ...loadingStates.value[index], ...updates }
    }
  }

  function stopLoading(id: string) {
    const index = loadingStates.value.findIndex(l => l.id === id)
    if (index > -1) {
      loadingStates.value.splice(index, 1)
    }
  }

  function stopAllLoading() {
    loadingStates.value = []
  }

  // Actions - Dialogs
  function showDialog(dialog: Omit<DialogState, 'id'>): string {
    const dialogState: DialogState = {
      id: generateId(),
      ...dialog
    }
    
    dialogs.value.push(dialogState)
    return dialogState.id
  }

  function showConfirm(
    title: string,
    message?: string,
    confirmText = '确认',
    cancelText = '取消'
  ): Promise<boolean> {
    return new Promise((resolve) => {
      showDialog({
        type: 'confirm',
        title,
        message,
        confirmText,
        cancelText,
        onConfirm: () => resolve(true),
        onCancel: () => resolve(false)
      })
    })
  }

  function showPrompt(
    title: string,
    message?: string,
    defaultValue = ''
  ): Promise<string | null> {
    return new Promise((resolve) => {
      showDialog({
        type: 'prompt',
        title,
        message,
        onConfirm: (value: string) => resolve(value || defaultValue),
        onCancel: () => resolve(null)
      })
    })
  }

  function closeDialog(id?: string) {
    if (id) {
      const index = dialogs.value.findIndex(d => d.id === id)
      if (index > -1) {
        dialogs.value.splice(index, 1)
      }
    } else {
      // Close the topmost dialog
      dialogs.value.pop()
    }
  }

  function closeAllDialogs() {
    dialogs.value = []
  }

  // Actions - UI State
  function toggleSidebar() {
    sidebarCollapsed.value = !sidebarCollapsed.value
  }

  function setSidebarCollapsed(collapsed: boolean) {
    sidebarCollapsed.value = collapsed
  }

  function setTheme(newTheme: 'light' | 'dark') {
    theme.value = newTheme
    // Apply theme to document
    document.documentElement.setAttribute('data-theme', newTheme)
  }

  function toggleTheme() {
    setTheme(theme.value === 'light' ? 'dark' : 'light')
  }

  function setCurrentView(view: typeof currentView.value) {
    currentView.value = view
  }

  function setKeyboardShortcutsEnabled(enabled: boolean) {
    keyboardShortcutsEnabled.value = enabled
  }

  function setAutoSave(enabled: boolean) {
    autoSave.value = enabled
  }

  function setLanguage(lang: 'zh' | 'en') {
    language.value = lang
  }

  function updateWindowSize(width: number, height: number) {
    windowSize.value = { width, height }
  }

  function updatePanelSize(panel: keyof typeof panelSizes.value, size: number) {
    panelSizes.value[panel] = size
  }

  function resetPanelSizes() {
    panelSizes.value = {
      sidebar: 300,
      main: 600,
      details: 300
    }
  }

  // Helper functions
  function generateId(): string {
    return Math.random().toString(36).substr(2, 9)
  }

  // Keyboard shortcuts
  const shortcuts = ref<Map<string, () => void>>(new Map())

  function registerShortcut(key: string, handler: () => void) {
    shortcuts.value.set(key, handler)
  }

  function unregisterShortcut(key: string) {
    shortcuts.value.delete(key)
  }

  function handleKeydown(event: KeyboardEvent) {
    if (!keyboardShortcutsEnabled.value) return
    
    const key = buildShortcutKey(event)
    const handler = shortcuts.value.get(key)
    
    if (handler) {
      event.preventDefault()
      handler()
    }
  }

  function buildShortcutKey(event: KeyboardEvent): string {
    const parts: string[] = []
    
    if (event.ctrlKey) parts.push('ctrl')
    if (event.altKey) parts.push('alt')
    if (event.shiftKey) parts.push('shift')
    if (event.metaKey) parts.push('meta')
    
    parts.push(event.key.toLowerCase())
    
    return parts.join('+')
  }

  // Initialize theme
  setTheme(theme.value)

  return {
    // State
    notifications,
    loadingStates,
    dialogs,
    sidebarCollapsed,
    theme,
    currentView,
    keyboardShortcutsEnabled,
    autoSave,
    language,
    windowSize,
    panelSizes,
    shortcuts,
    
    // Getters
    hasNotifications,
    hasLoadingStates,
    hasDialogs,
    isLoading,
    currentDialog,
    unreadNotifications,
    persistentNotifications,
    
    // Actions - Notifications
    showNotification,
    showSuccess,
    showError,
    showWarning,
    showInfo,
    removeNotification,
    clearNotifications,
    clearNotificationsByType,
    
    // Actions - Loading
    startLoading,
    updateLoading,
    stopLoading,
    stopAllLoading,
    
    // Actions - Dialogs
    showDialog,
    showConfirm,
    showPrompt,
    closeDialog,
    closeAllDialogs,
    
    // Actions - UI State
    toggleSidebar,
    setSidebarCollapsed,
    setTheme,
    toggleTheme,
    setCurrentView,
    setKeyboardShortcutsEnabled,
    setAutoSave,
    setLanguage,
    updateWindowSize,
    updatePanelSize,
    resetPanelSizes,
    
    // Actions - Shortcuts
    registerShortcut,
    unregisterShortcut,
    handleKeydown
  }
})